package com.nervenets.shopping.event;

import com.nervenets.general.utils.JodaUtils;
import com.nervenets.shopping.hibernate.domain.user.User;
import com.nervenets.shopping.service.DataOfUserService;
import com.nervenets.shopping.service.GroupBuyOrderUserService;
import com.nervenets.shopping.service.RechargeOrderService;
import com.nervenets.shopping.service.UserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;

@Slf4j
@AllArgsConstructor
public class DataOfUserEventListener {
    private final DataOfUserService dataOfUserService;
    private final UserService userService;
    private final RechargeOrderService rechargeOrderService;
    private final GroupBuyOrderUserService groupBuyOrderUserService;

    @Async
    @Order(0)
    @EventListener(DataOfUserEvent.class)
    public void handle(DataOfUserEvent event) {
        try {
            Thread.sleep(1000);

            DataOfUserEvent.Type type = (DataOfUserEvent.Type) event.getSource();
            long newer = 0, pay = 0, active = 0, refund = 0;
            long startOfToday = JodaUtils.getStartOfToday();
            long endOfToday = JodaUtils.getEndOfToday();
            switch (type) {
                case newer:
                    newer = userService.count((predicates, root, query, builder) -> predicates.add(builder.between(root.get("createTime"), startOfToday, endOfToday)));
                    break;
                case pay:
                    pay = rechargeOrderService.count((predicates, root, query, builder) -> predicates.add(builder.between(root.get("createTime"), startOfToday, endOfToday)));
                    pay += groupBuyOrderUserService.count((predicates, root, query, builder) -> predicates.add(builder.between(root.get("payTime"), startOfToday, endOfToday)));
                    break;
                case refund:
                    refund = rechargeOrderService.count((predicates, root, query, builder) -> predicates.add(builder.between(root.get("refundTime"), startOfToday, endOfToday)));
                    refund += groupBuyOrderUserService.count((predicates, root, query, builder) -> predicates.add(builder.between(root.get("refundTime"), startOfToday, endOfToday)));
                    break;
            }
            active = userService.count((predicates, root, query, builder) -> predicates.add(builder.between(root.get("lastLoginTime"), startOfToday, endOfToday)));
            dataOfUserService.updateData(newer, pay, active, refund);

            if (DataOfUserEvent.Type.newer.equals(type)) {
                User user = userService.findOne(event.getUserId());
                if (null != user && user.getParentId() > 0) {
                    userService.updateInviteCount(
                            userService.count((predicates, root, query, builder) -> predicates.add(builder.equal(root.get("parentId"), user.getParentId()))),
                            user.getParentId());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
